/*! \file TcpSession.h The TcpSession parent class. */
#ifndef __TCP_SESSION_H_INCLUDED__
#define __TCP_SESSION_H_INCLUDED__

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <list>
#include <boost/shared_ptr.hpp>

using boost::asio::ip::tcp;


/*! \brief the TcpSession class.
 *
 *  Note that this class derives from boost::enable_shared_from_this which allows
 *  us to leave the lifetime handling of the object to the shared_ptr implementation.
 *  very handy.
 *
 */
class TcpSession : public boost::enable_shared_from_this<TcpSession>
{
private:
	tcp::socket socket_;	
	boost::asio::streambuf m_ReadBuffer;
	void startRead ( );
	typedef std::list<std::string> MessageQueue;
	MessageQueue m_Outgoing;
	std::string m_OutgoingBuffer;
	bool m_Sending;
	boost::mutex m_Mutex;
	void handle_read(const boost::system::error_code& error, size_t bytes_transferred);
	void handle_write(const boost::system::error_code& error);
	void processOutgoing( );
	/*! \brief called when data arrives on the socket that is terminated by a \\r\\n */
	virtual bool dataReceived ( const char * data, size_t len ) = 0;
public:
  TcpSession(boost::asio::io_service& io_service);
  virtual ~TcpSession() {};
  tcp::socket& socket();
  virtual void start();

  /*! \brief Sends data over the session */
  void send( const std::string & data );
};
typedef boost::shared_ptr<TcpSession> TcpSessionPtr;

#endif